package com.ae.shield.common.enchantment.shieldSuffix;

import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.ae.shield.common.enchantment.EnchantmentWrap;
import com.ae.shield.common.items.shieldFittings.makers.ShieldMakerBase;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.registries.ForgeRegistries;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Map;

/**
 * 用于处理护盾后缀的相关内容
 */
public class SuffixFactory {
    /**
     * @param object 包含后缀的json
     * @return  json中存储的后缀，若未找到则返回null
     */
    @Nullable
    public static EnchantmentWrap deserializeSuffix(JsonObject object) {
        if (!JSONUtils.hasField(object, "suffix_name")) {
            return null;
        }

        String s = JSONUtils.getString(object, "suffix_name");
        Enchantment enchantment = ForgeRegistries.ENCHANTMENTS.getValue(new ResourceLocation(s));
        if (!(enchantment instanceof SuffixBase)) {
            throw new JsonSyntaxException("未知的后缀 '" + s + "'");
        }

        int level = JSONUtils.getInt(object, "lvl", 1);
        return EnchantmentWrap.wrap(enchantment, level);
    }
    /**
     * 获取指定ShieldMakerBase的所有后缀
     *
     * @param stack 传入需要获取后缀的ShieldMakerBase
     * @return 仅包含后缀的Map
     */
    public static Map<Enchantment, Integer> getSuffixes(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)) {
            return Collections.emptyMap();
        }

        //获取后缀
        Map<Enchantment, Integer> suffixes = EnchantmentHelper.getEnchantments(stack);

        if (suffixes.isEmpty()) {
            return Collections.emptyMap();
        }

        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            if (!(entry.getKey() instanceof SuffixBase)) {
                suffixes.remove(entry.getKey());
            }
        }

        return suffixes;
    }

    /**
     * 求得后缀修饰后的值
     *
     * @param rounding 是否四舍五入
     * @param base     基础值
     * @param suffix   各个后缀值
     */
    private static float suffixesSum(boolean rounding, float base, float[][] suffix) {
        float add = 0f;
        float multiply = 1f;
        float finalMultiply = 1f;

        for (float[] v : suffix) {
            switch ((int) v[1]) {
                case 0:
                    add += v[0];
                    break;
                case 1:
                    multiply += v[0];
                    break;
                case 2:
                    finalMultiply *= v[0];
            }
        }

        float sum = (base + add) * multiply * finalMultiply;

        return rounding ? Math.round(sum) : sum;
    }

    //TODO 改为用反射来减少重复代码？
    public static float maxIntensity(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getMaxIntensity();
        }

        float[][] intensities = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            intensities[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.INTENSITY, suffix.intensity[0]), suffix.intensity[1]};
        }

        //若原本不为0，则避免返回值小于0
        float finalCount = suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getMaxIntensity(), intensities);
        if (((ShieldMakerBase)stack.getItem()).getMaxIntensity() > 0 && finalCount <= 1) {
            return 1f;
        }

        return finalCount;
    }

    public static float upperLimit(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getUpperLimit();
        }

        float[][] upperLimit = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            upperLimit[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.UPPER_LIMIT, suffix.upperLimit[0]), suffix.upperLimit[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getUpperLimit(), upperLimit);
    }

    public static float floorLimit(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getFloorLimit();
        }

        float[][] floorLimit = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            floorLimit[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.FLOOR_LIMIT, suffix.floorLimit[0]), suffix.floorLimit[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getFloorLimit(), floorLimit);
    }

    public static float recovery(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getRecovery();
        }

        float[][] recovery = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            recovery[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.RECOVERY, suffix.recovery[0]), suffix.recovery[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getRecovery(), recovery);
    }

    public static float close(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getClose();
        }

        float[][] close = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            close[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.CLOSE, suffix.close[0]), suffix.close[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getClose(), close);
    }

    public static float remote(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getRemote();
        }

        float[][] remote = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            remote[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.REMOTE, suffix.remote[0]), suffix.remote[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getRemote(), remote);
    }

    public static float magic(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getMagic();
        }

        float[][] magic = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            magic[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.MAGIC, suffix.magic[0]), suffix.magic[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getMagic(), magic);
    }

    public static float other(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getOther();
        }

        float[][] other = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            other[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.OTHER, suffix.other[0]), suffix.other[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getOther(), other);
    }

    public static float penalty(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getOther();
        }

        float[][] penalty = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            penalty[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.PENALTY, suffix.penalty[0]), suffix.penalty[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getPenalty(), penalty);
    }

    public static int maxPiles(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getMaxPiles();
        }

        float[][] piles = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            piles[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.PILES, suffix.piles[0]), suffix.piles[1]};
        }

        float finalCount = suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getMaxPiles(), piles);
        if (((ShieldMakerBase)stack.getItem()).getMaxPiles() > 0 && finalCount <= 1) {
            return 1;
        }
        return (int) finalCount;
    }

    public static int recoverCost(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getCost();
        }

        float[][] cost = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            cost[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.COST, suffix.cost[0]), suffix.cost[1]};
        }
        return (int) suffixesSum(true, ((ShieldMakerBase) stack.getItem()).getCost(), cost);
    }

    public static float cd(ItemStack stack) {
        if (!(stack.getItem() instanceof ShieldMakerBase)){
            throw new IllegalArgumentException("输入的 ItemStack 不是 ShieldMakerBase。 输入的参数是 " + stack.getItem() + " 。");
        }

        Map<Enchantment, Integer> suffixes = getSuffixes(stack);

        if (suffixes.isEmpty()){
            return ((ShieldMakerBase) stack.getItem()).getMaxCD();
        }

        float[][] cd = new float[suffixes.size()][2];
        int count = -1;
        for (Map.Entry<Enchantment, Integer> entry : suffixes.entrySet()) {
            SuffixBase suffix = (SuffixBase) entry.getKey();
            cd[++ count] = new float[]{suffix.levelRate(entry.getValue(), SuffixProperty.CD, suffix.cd[0]), suffix.cd[1]};
        }
        return suffixesSum(false, ((ShieldMakerBase) stack.getItem()).getMaxCD(), cd);
    }
}
